package com.zoro.barn.business.service.system.business.user.service;

import com.zoro.barn.commons.db.autopage.PageParamFilter;
import com.zoro.barn.business.service.system.business.systeminfo.dao.BarnSystemInfoMapper;
import com.zoro.barn.business.service.system.business.systeminfo.entity.BarnSystemInfo;
import com.zoro.barn.business.service.system.business.user.entity.BarnUser;
import com.zoro.barn.business.service.system.business.user.dao.BarnUserMapper;
import com.zoro.barn.commons.redis.annotations.CacheDuration;
import com.zoro.barn.commons.redis.annotations.UseCacheDurationConfig;
import com.zoro.barn.commons.redis.cache.AbstractKeyGenerator;
import com.zoro.barn.commons.tools.encryption.EncryptUtils;
import com.zoro.barn.commons.tools.string.IDs;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @author zhaoxingwu
 */
@Service
@UseCacheDurationConfig
@CacheDuration(60 * 60 * 1000)
public class BarnUserService {

    @Resource
    private BarnUserMapper barnUserMapper;

    @Resource
    private BarnSystemInfoMapper barnSystemInfoMapper;

    /**
     * query barn-users by {@code param}
     *
     * @param param parameters
     * @return result set
     */
    @Cacheable(cacheNames = "BARN_USER_QUERY", keyGenerator = "barn_user_cache_key_generator")
    public List<BarnUser> query(BarnUser param) {
        return this.barnUserMapper.query(param);
    }

    /**
     * 保存数据 如果 {@link BarnUser#getPid()} 不为空，update , 否则 insert
     *
     * @param data 需要保存的数据
     * @return data
     */
    @Transactional(rollbackFor = Exception.class)
    @Caching(evict = {
            @CacheEvict(cacheNames = "BARN_USER_QUERY", allEntries = true),
            @CacheEvict(cacheNames = "BARN_USER_GET_ID", key = "#a0?.pid+'_'")
    })
    public BarnUser save(BarnUser data) {
        if (StringUtils.isBlank(data.getPid())) {
            data.setPid(IDs.uuid());
            data.setCreateTime(new Date());
            BarnSystemInfo systemInfo = barnSystemInfoMapper.getById("DEFAULT_PASSWORD");
            if (systemInfo != null && StringUtils.isNotBlank(systemInfo.getVariableValue())) {
                data.setPassword(EncryptUtils.md5Encode(systemInfo.getVariableValue()));
            } else {
                data.setPassword(EncryptUtils.md5Encode("1"));
            }
            this.barnUserMapper.insert(data);
        } else {
            data.setUpdateTime(new Date());
            this.barnUserMapper.update(data);
        }
        data.setPassword(null);
        return data;
    }

    @Cacheable(cacheNames = "BARN_USER_GET_ID", key = "#a0+'_'")
    public BarnUser getById(String pid) {
        return this.barnUserMapper.getById(pid);
    }

    @Component("barn_user_cache_key_generator")
    private static class BarnUserCacheKeyGenerator extends AbstractKeyGenerator<BarnUser> {

        @Override
        public String generate(BarnUser param) {
            return param.getUserName() + "::" + param.getUserAccount() + "::" + param.getEnable() + "::" + PageParamFilter.currentPage() + "::" + PageParamFilter.pageSize();
        }

        @Override
        public Class<BarnUser> supportClass() {
            return BarnUser.class;
        }
    }
}
